Skip to content

Extend the auth-attempt contract for credential refresh - #78

Merged
wch merged 6 commits into
mainfrom
external-browser-auth
Aug 25, 2026
Merged

Extend the auth-attempt contract for credential refresh#78
wch merged 6 commits into
mainfrom
external-browser-auth

Conversation

@wch

@wch wch commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Consumers that refresh expired credentials (for example AWS SSO or Google ADC) can't express two common outcomes with the current attempt contract: a refresh that finishes synchronously with no user interaction, and a refresh that can't be attempted at all in the current environment. They also can't represent a login flow whose browser step is owned by an external process like a spawned CLI. Callers have to fake these cases with errors or side channels.

This PR extends the authentication contract in ai-credentials with three additions. A new external-browser challenge kind describes a flow where an external process (such as gcloud) owns the browser step, with display instructions and an optional URL. A completed start result covers synchronous refreshes — such as a silent token refresh — that create no attempt and just tell the caller to refetch auth status. An unavailable start result with a reason covers cases where no attempt can be created (missing CLI, no SSO profile, no reachable browser), so the caller can fall back to a configuration UI.

All additions are new union members, so existing consumers compile and behave unchanged. The new contract is covered by attempt-contract tests.

Changes

  • AuthenticationChallenge gains an external-browser kind for flows where a spawned process owns the browser step. Previously, only interactive URL-based challenges could be expressed.
  • AuthenticationStartResult gains completed and unavailable statuses. Previously, a start call could only report started or already-in-progress, leaving no way to express synchronous success or environment-level unavailability.

wch added 6 commits August 22, 2026 19:45
Extends the authentication attempt contract for in-app credential
refresh (e.g. expired AWS SSO / Google ADC sessions):

- New 'external-browser' challenge kind for flows where an external
  process (spawned CLI) owns the browser; carries attemptId, expiresIn,
  instructions, and an optional url.
- New 'unavailable' AuthenticationStartResult variant meaning no
  attempt was created (required CLI missing, no SSO profile, etc.) so
  callers can fall back to a configuration UI instead of catching a
  throw.

Duplicate-start ownership (already-in-progress) and disposal-cancel
semantics are unchanged; the new variants are purely additive.
A silent (browser-free) token refresh finishes inside
startAuthentication — no attempt is created, nothing is polled or
cancelled — so the attempt contract needs a way to say 'already done;
refetch status and models'. The interactive paths are unchanged and
still ride attempts end to end.
These tests constructed typed literals and asserted the same literals
back, so they could not detect a behavioral regression — TypeScript
already supplies their only useful coverage. The protocol handler and
standalone tests cover the real pass-through and rendering behavior.
Hosts with a graphical configuration overlay rewrite the credential-expiry
toast to a Reconnect action that opens the overlay and starts an in-app
credential refresh. The bridge keeps emitting REFRESH_MODELS with CLI copy
as its host-agnostic default; the rewrite happens in the Node provider
callbacks when the host opts in.
@wch
wch merged commit 14ebc88 into main Aug 25, 2026
4 checks passed
@wch
wch deleted the external-browser-auth branch August 25, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant